package com.yungam.imcs.controller.hand_inspect.day;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.yungam.common.bean.hand_inspect.ProcessInspectionHand;
import com.yungam.common.bean.hand_inspect.ProductInspectionHand;
import com.yungam.common.bean.process.ProductProcess;
import com.yungam.common.bean.process.ProductionProcess;
import com.yungam.common.bean.product.ProductionProduct;
import com.yungam.common.response.RetDTO;
import com.yungam.common.service.ProcessInspectionHandService;
import com.yungam.common.service.ProductInspectionHandService;
import com.yungam.common.service.ProductionProcessService;
import com.yungam.common.service.ProductionProductService;
import com.yungam.common.utils.DateUtils;
import com.yungam.imcs.utils.ProductUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Api(tags = "今日质量检验页面接口")
@RestController
@RequestMapping("/day_inspection")
public class DayHandInspectionController {

    @Resource
    private DateUtils dateUtils;
    @Resource
    private ProductUtils productUtils;
    @Resource
    private ProductInspectionHandService productInspectionHandService;
    @Resource
    private ProcessInspectionHandService processInspectionHandService;
    @Resource
    private ProductionProductService productionProductService;
    @Resource
    private ProductionProcessService productionProcessService;

    @ApiOperation("获取表格数据")
    @GetMapping("/tableData")
    public RetDTO<?> getDayTableData() {
        check();

        // 查询
        String[] range = dateUtils.getTodayRange();
        String start = range[0], end = range[1];
        List<ProductInspectionHand> productHands = productInspectionHandService.list(new QueryWrapper<ProductInspectionHand>()
                .between("create_time", start, end).orderByDesc("create_time"));
        List<ProcessInspectionHand> processHands = processInspectionHandService.list(new QueryWrapper<ProcessInspectionHand>()
                .between("create_time", start, end).orderByAsc("create_time"));

        // 组装成树结构
        Map<String, List<ProcessInspectionHand>> map = Maps.newHashMap();
        for (ProcessInspectionHand ph : processHands) {
            List<ProcessInspectionHand> list = map.getOrDefault(ph.getProductSn(), Lists.newArrayList());
            list.add(ph);
            map.put(ph.getProductSn(), list);
        }

        for (ProductInspectionHand productHand : productHands) {
            productHand.setChildren(map.getOrDefault(productHand.getProductSn(), null));
        }

        return RetDTO.data(productHands);
    }

    /* 查询数据前的检验
    *  需要检查 production_product 表  每当有新罐子完成, 需要对 product_inspection_hand 插入一条数据 (process_inspection_hand 同理)
    * */
    @Scheduled(fixedRate = 1000 * 60 * 60)
    private void check() {
        String[] range = dateUtils.getTodayRange();
        String start = range[0], end = range[1];
        // ProductInspectionHand 已经插入的数据
        List<ProductInspectionHand> products = productInspectionHandService.list(new QueryWrapper<ProductInspectionHand>()
                .between("create_time", start, end));

        // 查询今日已经完成的罐子
        List<ProductionProduct> finished = productUtils.getFinishedProduct();
        List<String> finishedNo = finished.stream()
                .map(ProductionProduct::getProductSn).collect(Collectors.toList());
        Map<String, String> map = Maps.newHashMap(); // 罐号 - 产品号映射
        for (ProductionProduct pp : finished) map.put(pp.getProductSn(), pp.getProductNo());

        // 没有新完成的罐子
        if (products.size() == finishedNo.size()) return;

        // 找出新完成的罐号
        List<String> refresh = Lists.newArrayList();

        List<String> old = products.stream()
                .map(ProductInspectionHand::getProductSn).collect(Collectors.toList());
        for (String s : finishedNo) {
            if (!old.contains(s)) refresh.add(s);
        }

        // 插入新罐子
        insert(refresh, map);
    }

    /**
     * 插入新完成的罐子到 product_inspection_hand & process_inspection_hand
     */
    private void insert(List<String> productSns, Map<String, String> map) {
        Map<String, List<ProductProcess>> pMap = Maps.newHashMap();
        // 根据产品号获取所有的工序号, 存入 Map  （产品号 - 工序）
        for (String value : map.values()) {
            List<ProductProcess> list = productUtils.getProcessByProductNo(value);
            pMap.put(value, list);
        }

        // 获取罐子和工序质量信息
        List<ProductionProduct> products = productionProductService.list(new QueryWrapper<ProductionProduct>()
                .in("product_sn", productSns).isNotNull("end_time").eq("state", 1));
        Map<String, Integer> productSnStateMap = Maps.newHashMap();
        for (ProductionProduct pp : products) productSnStateMap.put(pp.getProductSn(), pp.getGood());

        List<ProductionProcess> processes = productionProcessService.list(new QueryWrapper<ProductionProcess>()
                .in("product_sn", productSns).isNotNull("end_time").eq("state", 1));
        Map<String, Integer> processSnStateMap = Maps.newHashMap();
        for (ProductionProcess pp : processes) {
            String key = pp.getProductSn() + "-" + pp.getProcessNo();
            processSnStateMap.put(key, pp.getGood());
        }

        List<ProductInspectionHand> productInsert = Lists.newArrayList();
        List<ProcessInspectionHand> processInsert = Lists.newArrayList();
        for (String productSn : productSns) {
            String productNo = map.get(productSn);
            // product_inspection_hand
            ProductInspectionHand pi = new ProductInspectionHand();
            pi.setProductSn(productSn);
            pi.setProductNo(productNo);
            pi.setCreateTime(new Date());
            Integer productSnGood = productSnStateMap.getOrDefault(productSn, null);
            pi.setState(productSnGood);
            productInsert.add(pi);

            List<ProductProcess> child = pMap.get(productNo);
            // process_inspection_hand
            for (ProductProcess pp : child) {
                ProcessInspectionHand pih = new ProcessInspectionHand();
                pih.setProductSn(productSn);
                pih.setProductNo(productNo);
                pih.setProcessNo(pp.getProcessNo());
                pih.setProcessName(pp.getProcessName());
                pih.setCreateTime(new Date());
                String key = productSn + "-" + pp.getProcessNo();
                Integer processGood = processSnStateMap.getOrDefault(key, null);
                pih.setState(processGood);
                processInsert.add(pih);
            }
        }

        productInspectionHandService.saveBatch(productInsert);
        processInspectionHandService.saveBatch(processInsert);
    }

    @ApiOperation("保存检验信息")
    @PostMapping("/save")
    public RetDTO<?> save(@ApiParam("产品检验实体集合") @RequestBody List<ProductInspectionHand> data) {
        int len = data.size();
        if (len == 0) return RetDTO.success();

        for (ProductInspectionHand pi : data) {
            productInspectionHandService.updateById(pi);
            if (pi.getChildren() == null || pi.getChildren().size() == 0)  continue;
            for (ProcessInspectionHand child : pi.getChildren()) {
                processInspectionHandService.updateById(child);
            }
        }

        return RetDTO.success();
    }

}
